package antempire.control.game.factory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;

import antempire.control.game.GameConstants;
import antempire.control.game.operation.ModelInformationController;
import antempire.control.game.operation.fishoperation.AntController;
import antempire.control.game.operation.fishoperation.AntOperation;
import antempire.control.record.Matrix;

public class AntFactory implements GameConstants {
	final Random random = new Random();	
	private Matrix matrix=new Matrix();
	private static AntFactory uniqueInstance;
	private AntFactory()
	{
	}
	
	public static AntFactory getInstance(){
		if(uniqueInstance == null){
			uniqueInstance = new AntFactory();
		}
		return uniqueInstance;
	}
	
	public AntController createSingleAnt(TiledTextureRegion antTextureRegion, Ant_Name name, Scene scene, Ant_Move antMove){
		AntController ant = new AntController(name, antTextureRegion);
		AntOperation antOperation=new AntOperation();
		antOperation.set_Controller(ant);
		ant.set_Ant_Operation(antOperation);
		antOperation.set_edge_position(Edge_Position.RANDOM);
		antOperation.set_side(Move_Direction.RANDOM);
		antOperation.set_Move(antMove);
		// ant.animate(100);
		switch(this.getDirection()) {
		case LEFT:
			ant.animate(new long[]{100, 100, 100}, 3, 5, true);
			break;
		case RIGHT:
			ant.animate(new long[]{100, 100, 100}, 9, 11, true);
			break;
		case UP:
			ant.animate(new long[]{100, 100, 100}, 6, 8, true);
			break;
		case DOWN:
			ant.animate(new long[]{100, 100, 100}, 0, 2, true);
			break;
		}
		ant.setSize(ModelInformationController.getInstance().getAntInformation(name).get_size_w(), 
				ModelInformationController.getInstance().getAntInformation(name).get_size_h());
	
		scene.getChild(LAYER_ANT).attachChild(ant);
		
		return ant;
	}
	
	public void createAnt(ArrayList<AntController> movingAntList,
			HashMap<Ant_Name, TiledTextureRegion> allAntTextureRegionMap, Scene scene){
		int randomListSize = (int) (Math.random()*ANTLIST_MAX);
		if(movingAntList.size() < randomListSize){
			for(int i = 0; i < randomListSize - movingAntList.size(); i++){
				Ant_Name antName = this.getAntName();
				/*if(antName == Ant_Name.MONOMORIUM || antName == Ant_Name.PHEIDOLE){
					Ant_Group_Way groupWay = this.getAntGroupWay();
					if(groupWay == Ant_Group_Way.Circle_Group)
						this.creat_Circle_Group(antName, movingAntList, allAntTextureRegionMap.get(antName), scene);
					else if(groupWay == Ant_Group_Way.Curve_Group)
						this.creat_Curve_Group(antName, movingAntList, allAntTextureRegionMap.get(antName), scene);
					else
						movingAntList.add(this.createSingleAnt(allAntTextureRegionMap.get(antName), antName, scene, this.getAntMove()));
					
				}else if(antName == Ant_Name.LOS || antName == Ant_Name.DOLICHODERINAE){
					movingAntList.add(this.createSingleAnt(allAntTextureRegionMap.get(antName), antName, scene, this.getAntMove()));
				}else
					movingAntList.add(this.createSingleAnt(allAntTextureRegionMap.get(antName), antName, scene, Ant_Move.Direct));*/
				movingAntList.add(this.createSingleAnt(allAntTextureRegionMap.get(antName), antName, scene, this.getAntMove()));
				
			}		
		}
	}


	private Ant_Group_Way getAntGroupWay() {
	 int i = (int) (Math.random()*10);
	 if(i < 2)
		 return Ant_Group_Way.Circle_Group;
	 else if( i >=2 && i < 6)
		 return Ant_Group_Way.Curve_Group;
	 else
		 return Ant_Group_Way.Random_Single;
}

	private Ant_Name getAntName() {
		int i = (int) (Math.random()*100);
		if(i < 20)
			return Ant_Name.MONOMORIUM;
		else if(i >=20 && i < 45)
			return Ant_Name.PHEIDOLE;
		else if(i >=45 && i < 75)
			return Ant_Name.LOS;
		else
			return Ant_Name.DOLICHODERINAE;
	}

	public void remove_ant(Scene scene,AntController ant)
	{
		scene.detachChild(ant);
	}
	
	private Ant_Move getAntMove()
	{
		int i=Math.abs(random.nextInt())%2;
		switch(i){
		case 0:{
			return Ant_Move.Direct;
		}
		case 1:{
			return Ant_Move.Curve;
		}
		}
		return Ant_Move.Direct;
	}
	
	private Move_Direction getDirection()
	{
		int i=Math.abs(random.nextInt())%4;
		switch(i){
		case 0:{
			return Move_Direction.RIGHT;
		}
		case 1:{
			return Move_Direction.LEFT;
		}
		case 2:{
			return Move_Direction.UP;
		}
		case 3:{
			return Move_Direction.DOWN;
		}
		}
		return Move_Direction.LEFT;
	}
	
	public void creat_Circle_Group(Ant_Name AntName, ArrayList<AntController> movingAntList,
			TiledTextureRegion antTextureRegion, Scene scene)
	{
		Move_Direction direction=this.getDirection();
		for(int i = 0; i < 5; i++){
				AntController ant = new AntController(AntName,antTextureRegion.clone());
				AntOperation antOperation=new AntOperation();
				antOperation.set_Controller(ant);
				ant.set_Ant_Operation(antOperation);
				if(i==0)
					antOperation.set_edge_position(Edge_Position.TOP);
				else if(i==1)
					antOperation.set_edge_position(Edge_Position.UP);
				else if(i==2)
					antOperation.set_edge_position(Edge_Position.MIDDLE);
				else if(i == 3) 
					antOperation.set_edge_position(Edge_Position.DOWN);
				else if(i == 4)
					antOperation.set_edge_position(Edge_Position.BOTTOM);
				antOperation.set_side(direction);
				antOperation.set_Circle_Move();
				switch(direction) {
				case LEFT:
					ant.animate(new long[]{100, 100, 100}, 3, 5, true);
					break;
				case RIGHT:
					ant.animate(new long[]{100, 100, 100}, 9, 11, true);
					break;
				case UP:
					ant.animate(new long[]{100, 100, 100}, 6, 8, true);
					break;
				case DOWN:
					ant.animate(new long[]{100, 100, 100}, 0, 2, true);
					break;
				}
				ant.setSize(ModelInformationController.getInstance().getAntInformation(AntName).get_size_w(), 
						ModelInformationController.getInstance().getAntInformation(AntName).get_size_h());
				
				movingAntList.add(ant);
			
				scene.getChild(LAYER_ANT).attachChild(ant);	
		}		
	}
	
	public void creat_Curve_Group(Ant_Name antName, ArrayList<AntController> movingAntList,
			TiledTextureRegion fishTextureRegion, Scene scene)
	{
		Move_Direction direction=this.getDirection();
		int a=Math.abs(random.nextInt())%41-20;
		while(a==0)
			a=Math.abs(random.nextInt())%41-20;
		
		for(int i = 0; i < 3; i++){
				AntController ant = new AntController(antName,fishTextureRegion.clone());
				AntOperation antOperation=new AntOperation();
				antOperation.set_Controller(ant);
				ant.set_Ant_Operation(antOperation);
				if(i==0)
					antOperation.set_edge_position(Edge_Position.UP);
				else if(i==1)
					antOperation.set_edge_position(Edge_Position.MIDDLE);
				else if(i==2)
					antOperation.set_edge_position(Edge_Position.DOWN);
				antOperation.set_side(direction);
				antOperation.set_Curve_Move(a);
				ant.animate(new long[]{100, 100, 100}, 3, 5, true);
				 // ant.animate(100);
				ant.setSize(ModelInformationController.getInstance().getAntInformation(antName).get_size_w(), 
						ModelInformationController.getInstance().getAntInformation(antName).get_size_h());
				
				movingAntList.add(ant);
			
				scene.getChild(LAYER_ANT).attachChild(ant);	
		}		
	}
	
	public void creat_String_Move(ArrayList<AntController> movingAntList,
			HashMap<Ant_Name, TiledTextureRegion> allAntTextureRegionMap, Scene scene,String str)
	{		
		int distance;
		distance=creat_Char_Move(movingAntList,allAntTextureRegionMap,scene,str.charAt(0),0)*38+38;	
		for(int i = 1; i < str.length(); i++){
			if(str.charAt(i)==' ')
				distance+=65;
			else
			 distance+=creat_Char_Move(movingAntList,allAntTextureRegionMap,scene,str.charAt(i),distance)*38+38;	
		}				
	}
	
	private int creat_Char_Move(ArrayList<AntController> movingAntList,
			HashMap<Ant_Name, TiledTextureRegion> allAntTextureRegionMap, Scene scene,char ch,int i)
	{
		Move_Direction direction=Move_Direction.LEFT;		
		int[][] c=matrix.get_Matrix(String.valueOf(ch));
	
		int column=c.length;
		int row=c[0].length;
		for(int t = 0; t < column; t++){
			for(int j=0;j < row; j++)
			{
				if(c[t][j]!=0)
				{
					AntController ant = new AntController(Ant_Name.MONOMORIUM,allAntTextureRegionMap.get(Ant_Name.MONOMORIUM).clone());
					AntOperation antOperation=new AntOperation();
					antOperation.set_Controller(ant);
					ant.set_Ant_Operation(antOperation);
					antOperation.set_side(direction);
					antOperation.set_fixed_Y(t*80+200);
					antOperation.set_fixed_X(-CAMERA_WIDTH-j*80+i*2);
					antOperation.set_Direct_Move(0);
					//ant.animate(150);
					ant.animate(new long[]{100, 100, 100}, 3, 5, true);
					ant.setSize(ModelInformationController.getInstance().getAntInformation(Ant_Name.MONOMORIUM).get_size_w(), 
							ModelInformationController.getInstance().getAntInformation(Ant_Name.MONOMORIUM).get_size_h());

					scene.getChild(LAYER_ANT).attachChild(ant);
					movingAntList.add(ant);
				}
			}
		}	
		return row;
	}

	public void createStartFishSequence(ArrayList<AntController> movingAntList,
			HashMap<Ant_Name, TiledTextureRegion> allAntTextureRegionMap,
			Scene scene) {
			this.creat_String_Move(movingAntList, allAntTextureRegionMap, scene, "HARD");
	}
}
